/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.bpm.engine.impl.bpmn.behavior;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.bpm.core.model.BpmnModel;
import com.je.bpm.core.model.FlowElement;
import com.je.bpm.core.model.SequenceFlow;
import com.je.bpm.core.model.button.TaskCommitBreakdownButton;
import com.je.bpm.core.model.button.factory.ButtonEnum;
import com.je.bpm.core.model.config.CounterSignPassTypeEnum;
import com.je.bpm.core.model.config.ProcessRemindTypeEnum;
import com.je.bpm.core.model.config.process.MessageSettingConfigImpl;
import com.je.bpm.core.model.config.process.ProcessRemindTemplate;
import com.je.bpm.core.model.config.task.TaskDismissConfigImpl;
import com.je.bpm.core.model.config.task.TaskPassRoundConfigImpl;
import com.je.bpm.core.model.event.StartEvent;
import com.je.bpm.core.model.process.Process;
import com.je.bpm.core.model.task.*;
import com.je.bpm.engine.approvalnotice.ActivitiApprovalNotice;
import com.je.bpm.engine.approvalnotice.TaskApprovalNoticeEnum;
import com.je.bpm.engine.delegate.DelegateExecution;
import com.je.bpm.engine.impl.cmd.DismissTaskCmd;
import com.je.bpm.engine.impl.context.Context;
import com.je.bpm.engine.impl.el.ExpressionManager;
import com.je.bpm.engine.impl.identity.Authentication;
import com.je.bpm.engine.impl.interceptor.CommandContext;
import com.je.bpm.engine.impl.persistence.entity.TaskEntity;
import com.je.bpm.engine.task.DelegationState;
import com.je.bpm.engine.task.Task;
import com.je.bpm.engine.upcoming.ActivitiUpcomingRun;
import com.je.bpm.engine.upcoming.UpcomingCommentInfoDTO;
import com.je.bpm.engine.upcoming.UpcomingDTO;

import java.util.*;
import java.util.stream.Collectors;

public class KaiteBaseUserTaskActivityBehavior extends KaiteTaskActivityBehavior {
    public static final String TASK_GLOBAL_VAR = "taskConfigs";

    protected static final String ASSIGNEE_VARIABLE = "${%s}";
    /**
     * 表单变量名称
     */
    public static final String FORM_VAR_NAME = "form";
    /**
     * 按钮变量名称
     */
    public static final String BUTTON_VAR_NAME = "buttons";
    /**
     * 自定义按钮
     */
    public static final String CUSTOMER_BUTTON_VAR_NAME = "customerButtons";
    /**
     * 上一个节点处理人可处理按钮
     */
    protected static final String PREVIOUS = "previous";
    /**
     * 当前节点可处理按钮
     */
    public static final String CURRENT = "current";
    /**
     * 任务变量名称
     */
    protected static final String TASK_VAR_NAME = "task";
    /**
     * 上一个节点处理人
     */
    public static final String PREV_ASSIGNEE = "prevAssignee";
    /**
     * 提交过来的节点id
     */
    public static final String DIRECT_TASK_ID = "directTaskId";
    /**
     * 提交过来的节点名称
     */
    public static final String DIRECT_TASK_NAME = "directTaskName";
    /**
     * 提交过来的target
     */
    public static final String DIRECT_TASK_TARGET = "directTarget";
    /**
     * 自定义提交
     */
    public static final String SUBMIT = "submit";
    /**
     * 自定义驳回
     */
    public static final String TURN_DOWN = "turnDown";
    /**
     * 是否是网关提交过来的
     */
    public static final String SUBMIT_IS_GATEWAY = "submitIsGateWay";

    public static final String UPCOMINGINFO = "upcomingInfo";

    public static final String SEQUENTIALS = "sequentials";
    /**
     * 随机节点处理人变量
     */
    public static final String RANDOM_TASK_ASSIGNEE = "randomTaskAssignee";

    /**
     * 处理任务配置
     */
    protected JSONObject handleBaseUserTaskConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, ExpressionManager expressionManager, BpmnModel bpmnModel) {
        JSONObject variableObj = new JSONObject();
        //任务配置
        JSONObject taskObj = new JSONObject();
        //表单配置
        JSONObject formObj = new JSONObject();
        //按钮配置
        JSONObject buttonObj = new JSONObject();
        buttonObj.put(CURRENT, "");
        buttonObj.put(PREVIOUS, "");
        formObj.put(BUTTON_VAR_NAME, buttonObj);
        JSONObject customerButtonObj = new JSONObject();
        List<Map<String, String>> customerSubmitList = new ArrayList<>();
        List<Map<String, String>> turnDownSubmitList = new ArrayList<>();
        customerButtonObj.put(SUBMIT, customerSubmitList);
        customerButtonObj.put(TURN_DOWN, turnDownSubmitList);
        formObj.put(CUSTOMER_BUTTON_VAR_NAME, customerButtonObj);
        variableObj.put(FORM_VAR_NAME, formObj);
        variableObj.put(TASK_VAR_NAME, taskObj);
        variableObj.put("startNode", false);
        //处理启动按钮变量
        handleStartConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        //处理提交按钮变量
        handleSubmitConfig(kaiteBaseUserTask, task, variableObj, expressionManager);
        //处理委托按钮变量
        handleDelegateConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        //处理取消委托按钮变量
        handleCancelDelegateConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        handleDismissConfig(kaiteBaseUserTask, task, variableObj);
        handleEarlyWarningConfig(kaiteBaseUserTask, variableObj);
        //判断当前节点的上一个节点是否是多人节点、或会签节点。如果是的话不显示退回按钮，变量不添加退回按钮变量
        boolean isMulti = false;
        List<Process> processes = bpmnModel.getProcesses();
        Collection<FlowElement> flowElements = processes.get(0).getFlowElements();
        for (FlowElement element : flowElements) {
            if (!(element instanceof SequenceFlow)) {
                continue;
            }
            SequenceFlow targetFlow = (SequenceFlow) element;
            FlowElement targetNode = targetFlow.getTargetFlowElement();
            if (targetNode != null && targetNode.getId().equals(kaiteBaseUserTask.getId())) {
                FlowElement sourceFlowElement = targetFlow.getSourceFlowElement();
                if (sourceFlowElement instanceof KaiteMultiUserTask) {
                    isMulti = true;
                }
                if (sourceFlowElement instanceof KaiteCounterSignUserTask) {
                    isMulti = true;
                }
            }
        }
        if (Context.getCommandContext().getAttribute(SUBMIT_IS_GATEWAY) == null) {
            handleGobackConfig(kaiteBaseUserTask, task, variableObj, bpmnModel, isMulti);
            //取回配置
            handleRetrieveConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
            //转办配置
            handleTransferConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        }
        handleJumpConfig(kaiteBaseUserTask, variableObj);
        handleInvalidConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        handleLabelCommentConfig(kaiteBaseUserTask, variableObj);
        handlePassRoundConfig(kaiteBaseUserTask, task, variableObj);
        handleUrgeConfig(task, kaiteBaseUserTask, variableObj, bpmnModel);

        handleRemindConfig(kaiteBaseUserTask, variableObj, bpmnModel);
        handleDefaultCommentConfig(kaiteBaseUserTask, variableObj);
        handleRevokeConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        handleCandidateUserConfig(kaiteBaseUserTask, variableObj);
        if (!variableObj.getBoolean("startNode")) {
            //TODO 直送后，这个值没有附上
            variableObj.getJSONObject(FORM_VAR_NAME).put(PREV_ASSIGNEE, task.getVariable(PREV_ASSIGNEE, String.class));
            variableObj.getJSONObject(FORM_VAR_NAME).put(DIRECT_TASK_ID, task.getVariable(DIRECT_TASK_ID, String.class));
            variableObj.getJSONObject(FORM_VAR_NAME).put(DIRECT_TASK_NAME, task.getVariable(DIRECT_TASK_NAME, String.class));
        }
        return variableObj;
    }

    /**
     * 候选
     */
    protected JSONObject handleCandidateUserConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variableObj) {
        if (kaiteBaseUserTask instanceof KaiteCandidateUserTask) {
            addButtonCode(variableObj, CURRENT, ButtonEnum.RECEIVE_BTN.getCode());
        }
        return variableObj;
    }

    /**
     * 会签
     */
    protected JSONObject handleCountersignedUserTaskConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, BpmnModel bpmnModel) {
        JSONObject variableObj = new JSONObject();
        //任务配置
        JSONObject taskObj = new JSONObject();
        //表单配置
        JSONObject formObj = new JSONObject();
        //按钮配置
        JSONObject buttonObj = new JSONObject();
        buttonObj.put(CURRENT, "");
        buttonObj.put(PREVIOUS, "");
        formObj.put(BUTTON_VAR_NAME, buttonObj);
        variableObj.put(FORM_VAR_NAME, formObj);
        variableObj.put(TASK_VAR_NAME, taskObj);
        variableObj.put("startNode", false);
        handleLabelCommentConfig(kaiteBaseUserTask, variableObj);
        handlePassRoundConfig(kaiteBaseUserTask, task, variableObj);
        handleUrgeConfig(task, kaiteBaseUserTask, variableObj, bpmnModel);
//        handleRetrieveConfig(kaiteBaseUserTask, task, variableObj, bpmnModel);
        handleRemindConfig(kaiteBaseUserTask, variableObj, bpmnModel);
        handleDefaultCommentConfig(kaiteBaseUserTask, variableObj);
        variableObj.getJSONObject(FORM_VAR_NAME).put(PREV_ASSIGNEE, task.getExecution().getVariable(PREV_ASSIGNEE, String.class));
        variableObj.getJSONObject(FORM_VAR_NAME).put(DIRECT_TASK_ID, task.getExecution().getVariable(DIRECT_TASK_ID, String.class));
        variableObj.getJSONObject(FORM_VAR_NAME).put(DIRECT_TASK_NAME, task.getExecution().getVariable(DIRECT_TASK_NAME, String.class));
        KaiteCounterSignUserTask kaiteCounterSignUserTask = (KaiteCounterSignUserTask) kaiteBaseUserTask;
        //运行时调整
        if (kaiteCounterSignUserTask.getCounterSignConfig().isRuntimeTuning()) {
            //更换负责人
            if (kaiteCounterSignUserTask.getCounterSignConfig().getCounterSignPassType().equals(CounterSignPassTypeEnum.PASS_PRINCIPAL)) {
                addButtonCode(variableObj, PREVIOUS, ButtonEnum.CHANGE_ASSIGNEE_BTN.getCode());
            }
            //加签
            addButtonCode(variableObj, PREVIOUS, ButtonEnum.COUNTERSIGNED_ADD_SIGNATURE_BTN.getCode());
            //减签
            addButtonCode(variableObj, PREVIOUS, ButtonEnum.COUNTERSIGNED_VISA_REDUCTION_BTN.getCode());
        }
        addButtonCode(variableObj, CURRENT, ButtonEnum.COUNTERSIGNED_PASS_BTN.getCode());
        addButtonCode(variableObj, CURRENT, ButtonEnum.COUNTERSIGNED_VETO_BTN.getCode());
        addButtonCode(variableObj, CURRENT, ButtonEnum.COUNTERSIGNED_ABSTAIN_BTN.getCode());
        return variableObj;
    }

    /**
     * 能否直送
     *
     * @return
     */
    private Boolean canDirectDelivery(TaskEntity task, KaiteBaseUserTask kaiteBaseUserTask) {
        Object dismissInfoObject = task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY);
        if (dismissInfoObject != null && dismissInfoObject instanceof Map) {
            Map<String, Object> dismissInfo = (Map<String, Object>) dismissInfoObject;
            if (dismissInfo.get(task.getTaskDefinitionKey()) != null) {
                Map<String, Object> currentNodeDismissInfo = (Map<String, Object>) dismissInfo.get(task.getTaskDefinitionKey());
                if (currentNodeDismissInfo.get("disableSendAfterDismiss") != null && (Boolean) currentNodeDismissInfo.get("disableSendAfterDismiss")) {
                    return false;
                }
                if (currentNodeDismissInfo.get("forceCommitAfterDismiss") != null && (Boolean) currentNodeDismissInfo.get("forceCommitAfterDismiss")) {
                    return true;
                }
                if (currentNodeDismissInfo.get("directSubmitAfterDismiss") != null && (Boolean) currentNodeDismissInfo.get("directSubmitAfterDismiss")) {
                    return true;
                }
            }
        }
        return false;
    }

    private Boolean canDirectDeliveryGoBack(TaskEntity task) {
        Object dismissInfoObject = task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY);
        if (dismissInfoObject != null && dismissInfoObject instanceof Map) {
            Map<String, Object> dismissInfo = (Map<String, Object>) dismissInfoObject;
            if (dismissInfo.get(task.getTaskDefinitionKey()) != null) {
                Map<String, Object> currentNodeDismissInfo = (Map<String, Object>) dismissInfo.get(task.getTaskDefinitionKey());
                if (currentNodeDismissInfo.get("directSendAfterReturn") != null && (Boolean) currentNodeDismissInfo.get("directSendAfterReturn")) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * 禁用提交
     *
     * @param task
     * @return
     */
    private Boolean disableCommit(TaskEntity task) {
        Object dismissInfoObject = task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY);
        if (dismissInfoObject != null && dismissInfoObject instanceof Map) {
            Map<String, Object> dismissInfo = (Map<String, Object>) dismissInfoObject;
            if (dismissInfo.get(task.getTaskDefinitionKey()) != null) {
                Map<String, Object> currentNodeDismissInfo = (Map<String, Object>) dismissInfo.get(task.getTaskDefinitionKey());
                if (currentNodeDismissInfo.get("forceCommitAfterDismiss") != null && (Boolean) currentNodeDismissInfo.get("forceCommitAfterDismiss")) {
                    return true;
                }
                if (currentNodeDismissInfo.get("disableSendAfterDismiss") != null && (Boolean) currentNodeDismissInfo.get("disableSendAfterDismiss")) {
                    return true;
                }
                if (currentNodeDismissInfo.get("directSendAfterReturn") != null && (Boolean) currentNodeDismissInfo.get("directSendAfterReturn")) {
                    return true;
                }
            }
        }
        return false;
    }

    //TODO 更换负责人任务领取按钮 传阅已阅

    /**
     * 启动，流程处于第一个节点
     * 发起，流程跳过第一个节点，到达第二个节点
     */
    protected void handleStartConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        FlowElement startElement = bpmnModel.getMainProcess().getFlowElements().stream().filter(flowElement -> flowElement instanceof StartEvent).collect(Collectors.toList()).get(0);
        List<SequenceFlow> outgoingFlows = ((StartEvent) startElement).getOutgoingFlows();
        String targetRef = outgoingFlows.get(0).getTargetRef();
        FlowElement firstTaskElement = bpmnModel.getFlowElement(targetRef);
        //如果是用户任务
        if (firstTaskElement.getId().equals(kaiteBaseUserTask.getId())) {
            //获取是否跳过的变量
            Boolean sponsor = Context.getCommandContext().getAttribute(CommandContext.IS_SPONSOR) != null ? (Boolean) Context.getCommandContext().getAttribute(CommandContext.IS_SPONSOR) : false;
            if (sponsor) {
                //如果是发起
                if (task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY) == null) {
                    variables.put("skip", true);
                }
            } else {
                variables.put("startNode", true);
            }
        }
    }

    /**
     * 撤销
     */
    protected void handleRevokeConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        if (!bpmnModel.getMainProcess().getExtendedConfiguration().isCanCancel()) {
            return;
        }
        FlowElement startElement = bpmnModel.getMainProcess().getFlowElements().stream().filter(flowElement -> flowElement instanceof StartEvent).collect(Collectors.toList()).get(0);
        List<SequenceFlow> outgoingFlows = ((StartEvent) startElement).getOutgoingFlows();
        String targetRef = outgoingFlows.get(0).getTargetRef();
        FlowElement firstTaskElement = bpmnModel.getFlowElement(targetRef);
        //如果是用户任务
        if ((firstTaskElement instanceof KaiteUserTask || firstTaskElement instanceof KaiteDecideUserTask)
                && firstTaskElement.getId().equals(kaiteBaseUserTask.getId())) {
//            if (variables.getBoolean("startNode") && !disableCommit(task)) {
            if (variables.getBoolean("startNode")) {
                if (!disableCommit(task)) {
                    addButtonCode(variables, CURRENT, ButtonEnum.CANCEL_BTN.getCode());
                }
            }
        }
    }


    private void addButtonCode(JSONObject variables, String type, String buttonCode) {
        JSONObject buttonObj = variables.getJSONObject(FORM_VAR_NAME).getJSONObject(BUTTON_VAR_NAME);
        String currentButtons = buttonObj.getString(type);
        variables.getJSONObject(FORM_VAR_NAME).getJSONObject(BUTTON_VAR_NAME).put(type, String.format("%s,%s", currentButtons, buttonCode));
    }

    private void addCustomerButtonCode(JSONObject variables, String type, Map<String, String> button) {
        JSONObject buttonObj = variables.getJSONObject(FORM_VAR_NAME).getJSONObject(CUSTOMER_BUTTON_VAR_NAME);
        List<Map<String, String>> currentButtons = (List<Map<String, String>>) buttonObj.get(type);
        currentButtons.add(button);
    }

    /**
     * 处理提交状态
     */
    protected void handleSubmitConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, ExpressionManager expressionManager) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        Boolean disableSubmitAfterDismiss = task.getVariable("directSubmitAfterDismiss", Boolean.class);
        Boolean disableSubmitAfterGoback = task.getVariable("disableSubmitAfterGoback", Boolean.class);
        //设置提交按钮是否可用状态，如果驳回或退回中只要任何一个拒绝提交操作，则提交按钮不可用
        if ((disableSubmitAfterDismiss == null || !disableSubmitAfterDismiss) && (disableSubmitAfterGoback == null || !disableSubmitAfterGoback)) {
            if (!disableCommit(task)) {
                addButtonCode(variables, CURRENT, ButtonEnum.SUBMIT_BTN.getCode());
                if (kaiteBaseUserTask instanceof KaiteDecideUserTask || kaiteBaseUserTask instanceof KaiteUserTask
                        || kaiteBaseUserTask instanceof KaiteFixedUserTask || kaiteBaseUserTask instanceof KaiteCandidateUserTask
                        || kaiteBaseUserTask instanceof KaiteLoopUserTask || kaiteBaseUserTask instanceof KaiteRandomUserTask) {
                    List<TaskCommitBreakdownButton> list = kaiteBaseUserTask.getCommitBreakdownButtonList();
                    for (TaskCommitBreakdownButton taskCommitBreakdownButton : list) {
                        Map<String, String> button = new HashMap<>();
                        button.put("nodeId", taskCommitBreakdownButton.getNodeId());
                        button.put("name", taskCommitBreakdownButton.getName());
                        button.put("nodeName", taskCommitBreakdownButton.getNodeName());
                        addCustomerButtonCode(variables, SUBMIT, button);
                    }
                }
            }
        }
    }

    /**
     * 处理委托状态
     */
    protected void handleDelegateConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }

        //如果启用委托，并且当前任务没有委托，则可以委托
        if (kaiteBaseUserTask.getTaskBasicConfig().getDelegate() && task.getDelegationState() == null) {
            //如果启用委托按钮
            if (!disableCommit(task)) {
                addButtonCode(variables, CURRENT, ButtonEnum.DELEGATE_BTN.getCode());
            }
        }
    }

    /**
     * 处理取消委托状态
     */
    protected void handleCancelDelegateConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }

        //如果委托状态启用，并且当前任务正在委托状态，则取消委托按钮可用
        if (kaiteBaseUserTask.getTaskBasicConfig().getDelegate() && task.getDelegationState() != null
                && task.getDelegationState().equals(DelegationState.PENDING)) {
            if (!disableCommit(task)) {
                addButtonCode(variables, PREVIOUS, ButtonEnum.CANCEL_DELEGATE_BTN.getCode());
            }
        }
    }

    /**
     * 处理驳回状态
     */
    protected void handleDismissConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables) {
        //多人节点不允许驳回
        if (isKaiteMultiUserTask(kaiteBaseUserTask)) {
            return;
        }
        TaskDismissConfigImpl taskDismissConfig = kaiteBaseUserTask.getTaskDismissConfig();
        if (taskDismissConfig.isEnable()) {
            if (!variables.getBoolean("startNode")) {
                addButtonCode(variables, CURRENT, ButtonEnum.DISMISS_BTN.getCode());
            }
        }
        //驳回后是否可以直接提交
        if (canDirectDelivery(task, kaiteBaseUserTask)) {
            addButtonCode(variables, CURRENT, ButtonEnum.DIRECT_SEND_BTN.getCode());
        }
    }

    /**
     * 处理退回配置
     */
    protected void handleGobackConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel, boolean... isMulti) {
        if (isMulti != null && isMulti.length == 1 && isMulti[0]) {
            return;
        }
        //多人节点不可退回
        if (isKaiteMultiUserTask(kaiteBaseUserTask)) {
            return;
        }
        Boolean processCanReturn = bpmnModel.getMainProcess().getExtendedConfiguration().isCanReturn();
        Boolean noReturn = kaiteBaseUserTask.getTaskDismissConfig().getNoReturn();
        //是否启用退回按钮
        if (processCanReturn && !noReturn) {
            if (!variables.getBoolean("startNode")) {
                if (!disableCommit(task)) {
                    addButtonCode(variables, CURRENT, ButtonEnum.GOBACK_BTN.getCode());
                }
            }
        }
        //退回后是否可以直接提交  directSendAfterDismiss forceCommitAfterDismiss
        if (canDirectDeliveryGoBack(task)) {
            addButtonCode(variables, CURRENT, ButtonEnum.DIRECT_SEND_BTN.getCode());
        }
    }

    /**
     * 判断是否是多人节点
     *
     * @param kaiteBaseUserTask
     * @return
     */
    private Boolean isKaiteMultiUserTask(KaiteBaseUserTask kaiteBaseUserTask) {
        if (kaiteBaseUserTask instanceof KaiteMultiUserTask) {
            return true;
        }
        if (kaiteBaseUserTask instanceof KaiteCounterSignUserTask) {
            return true;
        }
        return false;
    }

    /**
     * 处理默认审批意见
     */
    //TODO 换位置，获取按钮里面进行赋值
    protected void handleDefaultCommentConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
//        TaskDefaultCommentConfigImpl taskDefaultCommentConfig = kaiteBaseUserTask.getTaskEarlyWarningAndPostponementConfig();
//        JSONObject taskObj = variables.getJSONObject(TASK_VAR_NAME);
//        if (!taskDefaultCommentConfig.getDefaultComments().isEmpty()) {
//            taskObj.put("defaultCommentConfigEnable", true);
//            taskObj.put("customDefaultComments", taskDefaultCommentConfig.getDefaultComments());
//        } else {
//            taskObj.put("defaultCommentConfigEnable", false);
//        }
    }

    /**
     * 处理预警功能配置
     */
    //TODO 后续处理
    protected void handleEarlyWarningConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
//        TaskEarlyWarningAndPostponementConfigImpl taskEarlyWarningConfig = kaiteBaseUserTask.getTaskEarlyWarningConfig();
        JSONObject taskObj = variables.getJSONObject(TASK_VAR_NAME);
//        if (taskEarlyWarningConfig.isEnabled()) {
//            taskObj.put("earlyWarningEnable", true);
//        } else {
//            taskObj.put("earlyWarningEnable", false);
//        }
    }

    /**
     * 处理跳跃配置
     */
    //TODO 后续处理
    protected void handleJumpConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
//        TaskJumpConfigImpl taskJumpConfig = kaiteBaseUserTask.getTaskJumpConfig();
//        JSONObject buttonObj = variables.getJSONObject(FORM_VAR_NAME).getJSONObject(BUTTON_VAR_NAME);
//        if (taskJumpConfig.isEnable()) {
//            buttonObj.put("buttonJumpEnable", true);
//        } else {
//            buttonObj.put("buttonJumpEnable", false);
//        }
    }


    /**
     * 处理流程作废配置
     */
    protected void handleInvalidConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        Boolean processIsCanInvalid = bpmnModel.getMainProcess().getExtendedConfiguration().isCanInvalid();
        if (processIsCanInvalid && kaiteBaseUserTask.getTaskBasicConfig().getInvalid()) {
            addButtonCode(variables, CURRENT, ButtonEnum.INVALID_BTN.getCode());
        }
    }

    /**
     * 处理标签意见配置
     */
    protected void handleLabelCommentConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
//        TaskLabelCommentConfigImpl taskLabelCommentConfig = kaiteBaseUserTask.getTaskLabelCommentConfig();
//        JSONObject taskObj = variables.getJSONObject(TASK_VAR_NAME);
//        if (!taskLabelCommentConfig.getLabelComments().isEmpty()) {
//            taskObj.put("labelCommentConfigEnable", true);
//            taskObj.put("labelComments", taskLabelCommentConfig.getLabelComments());
//        } else {
//            taskObj.put("labelCommentConfigEnable", false);
//        }
    }

    /**
     * 处理任务传阅配置
     */
    protected void handlePassRoundConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        TaskPassRoundConfigImpl taskPassRoundConfig = kaiteBaseUserTask.getTaskPassRoundConfig();
        String buttonObj = variables.getJSONObject(FORM_VAR_NAME).getString(BUTTON_VAR_NAME);
        if (taskPassRoundConfig.isEnable() && !disableCommit(task)) {
            //如果开启自动传阅，必须是表单传阅，人员传阅，自定义服务传阅，启动人传阅
            if (!taskPassRoundConfig.isAuto() && taskPassRoundConfig.isEnable()) {
                addButtonCode(variables, CURRENT, ButtonEnum.PASSROUND_BTN.getCode());
            }
        }
    }

    /**
     * 处理催办配置
     */
    protected void handleUrgeConfig(TaskEntity task, KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        Boolean processIsCanUrged = bpmnModel.getMainProcess().getExtendedConfiguration().isCanUrged();
        if (processIsCanUrged && kaiteBaseUserTask.getTaskBasicConfig().getUrge()) {
            if (!variables.getBoolean("startNode")) {
                if (task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY) == null) {
                    addButtonCode(variables, PREVIOUS, ButtonEnum.URGE_BTN.getCode());
                }
            }
        }
    }

    /**
     * 处理转办配置
     */
    protected void handleTransferConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        Boolean processIsCanTransfer = bpmnModel.getMainProcess().getExtendedConfiguration().isCanTransfer();
        String directTaskId = task.getVariable(DIRECT_TASK_ID, String.class);
        FlowElement directTask = bpmnModel.getFlowElement(directTaskId);
        //退回，驳回操作去掉转办按钮
        if (Context.getCommandContext().getAttribute("isVeto") != null) {
            return;
        }
        if (canDirectDeliveryGoBack(task)) {
            return;
        }

        //前置节点是单人节点
        if (directTask instanceof KaiteFixedUserTask || directTask instanceof KaiteDecideUserTask || directTask instanceof KaiteUserTask) {
            Boolean taskCanTransfer = kaiteBaseUserTask.getTaskBasicConfig().getTransfer();
            if (processIsCanTransfer && taskCanTransfer) {
                if (!variables.getBoolean("startNode")) {
                    if (!disableCommit(task)) {
                        if (task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY) == null) {
                            addButtonCode(variables, PREVIOUS, ButtonEnum.TRANSFER_BTN.getCode());
                        }
                    }
                }
            }
        } else {
            return;
        }
    }

    /**
     * 处理取回配置
     */
    protected void handleRetrieveConfig(KaiteBaseUserTask kaiteBaseUserTask, TaskEntity task, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }
        Boolean processIsCanRetrieve = bpmnModel.getMainProcess().getExtendedConfiguration().isCanRetrieve();
        String directTaskId = task.getVariable(DIRECT_TASK_ID, String.class);
        FlowElement directTask = bpmnModel.getFlowElement(directTaskId);
        if (directTask instanceof KaiteBaseUserTask) {
            if (directTask instanceof KaiteCounterSignUserTask ||
                    directTask instanceof KaiteCandidateUserTask ||
                    directTask instanceof KaiteLoopUserTask ||
                    directTask instanceof KaiteMultiUserTask) {
                return;
            }
            Boolean taskCanRetrieve = ((KaiteBaseUserTask) directTask).getTaskBasicConfig().getRetrieve();
            if (processIsCanRetrieve && !taskCanRetrieve) {
                if (!variables.getBoolean("startNode")) {
                    if (!disableCommit(task)) {
                        if (task.getVariable(DismissTaskCmd.DISMISS_INFO_KEY) == null) {
                            addButtonCode(variables, PREVIOUS, ButtonEnum.RETRIEVE_BTN.getCode());
                        }
                    }
                }
            }
        } else {
            return;
        }
    }


    /**
     * 处理提醒配置
     */
    protected void handleRemindConfig(KaiteBaseUserTask kaiteBaseUserTask, JSONObject variables, BpmnModel bpmnModel) {
        //如果跳过，则不做相应状态配置处理
        if (variables.containsKey("skip") && variables.getBoolean("skip")) {
            return;
        }

        if (kaiteBaseUserTask.getTaskBasicConfig().getRemind()) {
            return;
        }

        MessageSettingConfigImpl messageSettingConfig = bpmnModel.getMainProcess().getMessageSetting();
        //模板
        List<ProcessRemindTemplate> remindTemplateList = messageSettingConfig.getMessageDefinitions();
        //推送方式
        List<ProcessRemindTypeEnum> remindTypeEnumList = messageSettingConfig.getMessages();
    }

    /**
     * 添加待办信息
     *
     * @param bpmnModel
     * @param execution
     * @param upcomingUserId
     */
    public void addUpcomingInfo(BpmnModel bpmnModel, DelegateExecution execution, String upcomingUserId, TaskEntity task, Boolean isSponsor) {
        String startUserId = "";
        if (task.getExecution().getProcessInstance().getStartUserId() != null) {
            startUserId = task.getExecution().getProcessInstance().getStartUserId();
        } else {
            startUserId = Authentication.getAuthenticatedUser().getDeptId();
        }
        ActivitiUpcomingRun activitiUpcomingRun = Context.getCommandContext().getProcessEngineConfiguration().getActivitiUpcomingRun();
        Object upcomingInfoObj = Context.getCommandContext().getAttribute(UPCOMINGINFO);
        if (upcomingInfoObj != null && upcomingInfoObj instanceof UpcomingCommentInfoDTO) {
            UpcomingCommentInfoDTO upcomingCommentInfoDTO = (UpcomingCommentInfoDTO) upcomingInfoObj;
            JSONArray jsonArray;
            if (!Strings.isNullOrEmpty(upcomingCommentInfoDTO.getAssigneeJson())) {
                jsonArray = JSONArray.parseArray(upcomingCommentInfoDTO.getAssigneeJson());
            } else {
                jsonArray = new JSONArray();
            }
            Boolean isIn = false;
            for (Object nodeInfo : jsonArray) {
                if (nodeInfo instanceof JSONObject) {
                    JSONObject jsonObject = (JSONObject) nodeInfo;
                    if (jsonObject.getString("nodeId").equals(task.getBusinessKey())) {
                        isIn = true;
                        break;
                    }
                }
            }
            if (isIn == false) {
                JSONObject assigneeUserJsonObject = new JSONObject();
                assigneeUserJsonObject.put("nodeId", task.getTaskDefinitionKey());
                assigneeUserJsonObject.put("nodeName", task.getName());
                assigneeUserJsonObject.put("assignee", task.getAssignee());
                assigneeUserJsonObject.put("assigneeName", "");
                jsonArray.add(assigneeUserJsonObject);
                upcomingCommentInfoDTO.setAssigneeJson(jsonArray.toJSONString());
                upcomingInfoObj = upcomingCommentInfoDTO;
            }
        }
        UpcomingDTO upcomingDTO = UpcomingDTO.build(bpmnModel, task, upcomingInfoObj, upcomingUserId, startUserId);
        activitiUpcomingRun.addUpcoming(upcomingDTO.setIsSponsor(isSponsor));
    }

    /**
     * 自动传阅
     */
    public void automaticCirculation(TaskEntity task, BpmnModel bpmnModel) {
        //多人节点只传阅一次
        if (Context.getCommandContext().getAttribute(task.getTaskDefinitionKey() + "automaticCirculation") != null) {
            return;
        }
        Context.getCommandContext().addAttribute(task.getTaskDefinitionKey() + "automaticCirculation", true);
        String taskId = task.getId();
        boolean isAuto = false;
        FlowElement flowElement = bpmnModel.getMainProcess().getFlowElementMap().get(task.getTaskDefinitionKey());
        if (flowElement instanceof KaiteBaseUserTask) {
            KaiteBaseUserTask kaiteBaseUserTask = (KaiteBaseUserTask) flowElement;
            isAuto = (kaiteBaseUserTask.getTaskPassRoundConfig().isEnable() && kaiteBaseUserTask.getTaskPassRoundConfig().isAuto());
        }
        if (isAuto) {
            Context.getCommandContext().getProcessEngineConfiguration().getTaskService()
                    .passRoundTask(taskId, new ArrayList<>(),
                            String.valueOf(Context.getCommandContext().getAttribute(CommandContext.PROD)),
                            task.getBusinessKey(), bpmnModel.getMainProcess().getProcessConfig().getTableCode(), task.getAssignee());
        }
    }

    /**
     * 添加审批告知
     */
    public void addApprovalNotice(CommandContext commandContext, DelegateExecution execution, TaskEntity task) {
        Object variable = commandContext.getAttribute(CommandContext.APPROVALNOTICE);
        if (variable instanceof JSONObject) {
            JSONObject jsonObject = (JSONObject) variable;
            //提交人
            String assignee = jsonObject.getString("assignee");
            //审批意见
            String comment = jsonObject.getString("comment");
            //提交类型name
            String submitType = jsonObject.getString("submitType");
            //审批告之事件配置类型
            List<TaskApprovalNoticeEnum> taskApprovalNoticeEnumList =
                    (List<TaskApprovalNoticeEnum>) jsonObject.get("approvalNoticeType");
            if (null == taskApprovalNoticeEnumList || taskApprovalNoticeEnumList.size() == 0) {
                return;
            }
            String toAssignee = "";
            List<Task> list = commandContext.getProcessEngineConfiguration().getTaskService().createTaskQuery().taskId(task.getId()).orderByTaskCreateTime().desc().list();
            if (null != list && list.size() > 0) {
                toAssignee = list.get(0).getAssignee();
            }
            if (Strings.isNullOrEmpty(toAssignee)) {
                toAssignee = task.getAssignee();
            }
            String beanId = task.getBusinessKey();
            String pdId = execution.getProcessDefinitionId();
            //获取bpmnModel
            BpmnModel bpmnModel = commandContext.getProcessEngineConfiguration().getRepositoryService().getBpmnModel(pdId);
            String modelName = bpmnModel.getMainProcess().getName();
            //获取审批告知的Bean信息
            ActivitiApprovalNotice approvalNotice = commandContext.getProcessEngineConfiguration().getActivitiApprovalNotice();
            //send
            approvalNotice.sendNotice(taskApprovalNoticeEnumList, execution, assignee, comment, submitType, toAssignee, modelName, beanId);
        }
    }

    public String getJustComment() {
        CommandContext commandContext = Context.getCommandContext();
        if (commandContext.getAttribute(commandContext.IS_JUMP) != null && commandContext.getAttribute(commandContext.IS_JUMP).equals("1")) {
            if (commandContext.getAttribute(commandContext.IS_JUMP_COMMENT) == null) {
                commandContext.addAttribute(commandContext.IS_JUMP_COMMENT, "1");
                if (commandContext.getAttribute(commandContext.COMMENT) == null) {
                    return "发起";
                } else {
                    return String.valueOf(commandContext.getAttribute(commandContext.COMMENT));
                }
            } else {
                return "系统自动跳跃通过";
            }
        }
        if (commandContext.getAttribute(commandContext.COMMENT) == null) {
            return "发起";
        } else {
            return String.valueOf(commandContext.getAttribute(commandContext.COMMENT));
        }
    }

}
